I2C Bus Adapter

The PROTOS miniHIL I2C abstraction offers an eTrice actor which provides an interface to connect multiple i2c slave simulations to one physical i2c bus. The bus adapter (AI2CBusAdapter) contains the hardware abstraction as well as a registration mechanism for the slave simulations.

To allow the simulations to react to incoming address requests in a timely manner the slaves register a callback function with the bus adapter. The registered callback is called from within the interrupt context once an address match occurred.

Note The I2C Abstraction currently only supports the simulation of I2C slaves.
Note Due to hardware restrictions currently all 10-Bit addressed slaves on the same bus must share the same value for the upper two address bits. I.e. 0x105 and 0x110 can be simulated using the same AI2CBusAdapter. 0x205 and 0x110 cannot be simulate using the same adapter.
Note If it is necessary to control the ACK/NACK reply for every received byte the I2CSlave_startReceive method must always be called with size = 1. As soon as a size > 1 is passed the single byte control (SBC) mode is exited. Outside of SBC mode a NACK will only be send after the next byte has been received. The current byte will be automatically ACKed.

Structure and usage flow

I2C Stack Example
An example I2C stack with 3 simulated slaves. The I2C Bus Hardware is provided by the miniHIL MCU. The I2C Bus adapter is part of the miniHILLib.
i2c sequence
A typical usage flow between one I2C Slave simulation, the Bus Adapter and the actual I2C Bus.

Details

The callback function type which can be registered with the i2c bus adapter
/**
 * type: Reason why this callback was called
 * direction: Transfer direction
 * packageBuffer: Buffer containing received bytes if a rx transfer was stated before
 * context: context to be used with i2c operations call from within the callback
 * userContext: a void pointer to a user defined target
 */
typedef void (i2cSlaveCallback_ft)(const I2CSlaveCallbackType type, const I2CTransferDirection direction, uint8_t * const packageBuffer, I2CContext * const context, void * const userContext);

The I2C hardware is configured to use clock stretching to stall the I2C clock till the user application is ready to provide new data. To end the clock stretching period the callback function must call one of the following I2C operations. If none of the operations is called the I2C bus will be stalled (clock is pulled low) till the master aborts the transfer by sending a stop condition.

I2C operations defined in I2C.h (SimRuntime/inc-platform). Each of the operations needs to be called with the i2c context passed into the callback function of the i2c simulation actor.
/**
 * Acks the current byte and starts transmitting size bytes from the contexts buffer.
 */
void I2CSlave_startTransmit(I2CContext * const context, uint8_t size);

/**
 * Acks the current byte and starts receiving size bytes.
 * context,
 * size: number of bytes to receive till the next callback
 */
void I2CSlave_startReceive(I2CContext * const context, uint8_t size);

/**
 * Nacks the current byte
 */
void I2CSlave_endTransfer(I2CContext const * const context);
Note Currently you can only create one instance of each AI2CBusAdapter actor in any given ROOM subsystem.